using System;
using Enyim.Caching;
using Enyim.Caching.Memcached;

namespace Web.Core.Extensions
{
    public static class MemcachedClientExtension
    {
        public static T Put<T>(this IMemcachedClient cache, string cacheKey, Func<T> sourceGetter) where T : class
        {
            return Get(
                (out T cacheData) => {
                    cacheData = cache.Get<T>(cacheKey);
                    return cacheData != null;
                },
                sourceGetter,
                cacheData => cache.Store(StoreMode.Set, cacheKey, cacheData));
        }

        public static T Put<T>(this IMemcachedClient cache, string cacheKey, Func<T> sourceGetter, DateTime expiresAt) where T : class
        {
            return Get(
                (out T cacheData) => {
                    cacheData = cache.Get<T>(cacheKey);
                    return cacheData != null;
                },
                sourceGetter,
                cacheData => cache.Store(StoreMode.Set, cacheKey, cacheData,expiresAt));
        }

        private delegate bool DataGetter<T>(out T data);

        private static T Get<T>(DataGetter<T> dataGetter, Func<T> sourceGetter, Action<T> dataSetter)
        {
            T data;
            if (dataGetter(out data))
            {
                return data;
            }
            data = sourceGetter();
            dataSetter(data);
            return data;
        }
    }
}